package top.eggcode.setup.config.shiro;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.session.mgt.DefaultSessionManager;
import org.apache.shiro.session.mgt.SessionKey;
import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
import org.apache.shiro.web.util.WebUtils;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.Serializable;

/**
 * Title: Http 会话管理
 * Description: 自定义 sessionId 获取
 * Date: 2021/6/10 9:10
 *
 * @author JiaQi Ding
 * @version 1.0
 */
public class HttpSessionManager extends DefaultSessionManager {

    /**
     * 会话标识的名称
     */
    public final static String SESSION_KEY_NAME = "Session-Id";

    /**
     * 覆盖父类的方法，当 shiro 获取 key 时会调用此方法。
     *
     * @param key 会话标识字段名称
     * @return 唯一标识
     */
    @Override
    public Serializable getSessionId(SessionKey key) {
        Serializable id = super.getSessionId(key);
        if (id == null && WebUtils.isWeb(key)) {
            ServletRequest request = WebUtils.getRequest(key);
            ServletResponse response = WebUtils.getResponse(key);
            id = this.getSessionId(request, response);
        }

        return id;
    }

    protected Serializable getSessionId(ServletRequest request, ServletResponse response) {
        return this.getReferencedSessionId(request, response);
    }

    /**
     * 从 header 中获取会话 key
     */
    protected Serializable getReferencedSessionId(ServletRequest request, ServletResponse response) {
        String id = WebUtils.toHttp(request).getHeader(SESSION_KEY_NAME);
        if (StringUtils.isEmpty(id)) {
            return null;
        } else {
            //如果请求头中有 token ，则参照源码设置三项
            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE, "header");
            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, id);
            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);
            return id;
        }
    }
}
